#! /usr/bin/python
# -*- coding: utf-8 -*-
'''
Created on Apr 2, 2013

@author: wu.qunfei@gmail.com
@describe: It's a mulit-screen player.
There is config.ini to make your own player.
x_amount: horizontal player amount
y_amount: vertical player amount
period_time: the period to change new stream program
machine_number: the mointor identity
address_server: the web server to arrage stream program
                response JSON data like stream.json 
'''


import wx
import vlc
import logging
import ConfigParser
import os
import urllib2
import urllib
import json
import time
import threading


class MakeMarquee(threading.Thread):
    def __init__(self, logger, player, streamName, streamPlatform, alarmSummary):
        threading.Thread.__init__(self)
        self.player = player
        self.title = streamName + "(" + streamPlatform + ") " + alarmSummary
        self.logger = logger
        self.alarmSummary = alarmSummary

    def run(self):
        try:
            time.sleep(5)
            try:
                volume = self.player.audio_get_volume()
                if volume == 0:
                    self.title += u"无音量"
            except Exception, e:
                self.logger.error(e)
            self.player.video_set_marquee_int(vlc.VideoMarqueeOption.Enable, 1)
            self.player.video_set_marquee_int(vlc.VideoMarqueeOption.Size, 48)
            self.player.video_set_marquee_int(vlc.VideoMarqueeOption.Position, 8)
            self.player.video_set_marquee_int(vlc.VideoMarqueeOption.Timeout, 0)
            self.player.video_set_marquee_string(vlc.VideoMarqueeOption.Text, self.title)
            if len(self.alarmSummary) > 0:
                self.player.video_set_marquee_int(vlc.VideoMarqueeOption.Color, 0xFF0000)
            else:
                self.player.video_set_marquee_int(vlc.VideoMarqueeOption.Color, 0xFFFFFF)
        except Exception, e:
            self.logger.error("Make Marquee failed")
            self.logger.error(e)


class Player(wx.Frame):
    def __init__(self, parent, title, logger):
        super(Player, self).__init__(parent, title=title, size=(600, 500))
        self.logger = logger
        cf = ConfigParser.ConfigParser()
        self.path = os.getcwd()
        try:
            configFileName = os.path.join(self.path, 'config.ini')
            cf.read(configFileName)
            self.playAddress = cf.get("default", "address_server")
            self.xAmount = cf.getint("default", "x_amount")
            self.yAmount = cf.getint("default", "y_amount")
            self.machineNumber = cf.getint("default", "machine_number")
            self.periodTime = cf.getint("default", "period_time")
        except Exception, e:
            self.logger.error("Can't read config.ini,application stop")
            self.logger.error(e)
            return
        self.vlc = vlc.Instance()
        self.players = []
        self.panels = []
        self.gs = None
        self.makeAllWindows()
        self.SetSizer(self.gs)
        self.Show(True)
        self.Center()
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.getPlayerAddress, self.timer)
        self.timer.Start(self.periodTime * 1000)
        # self.getPlayerLocal(None)

    def makeAllWindows(self):
        try:
            self.gs = wx.GridSizer(self.yAmount, self.xAmount, 0, 0)
            for x in range(self.xAmount):
                for y in range(self.yAmount):
                    player = self.vlc.media_player_new()
                    self.players.append(player)
                    panel = wx.Panel(self, -1)
                    panel.SetBackgroundColour(wx.BLACK)
                    self.panels.append(panel)
                    self.gs.Add(panel, 0, wx.EXPAND)
        except Exception, e:
            self.logger.error("Can't init all windows panel")
            self.logger.error(e)

    def getPlayerLocal(self, event):
        streamAmount = self.xAmount * self.yAmount
        fileHandler = open("streams.json", "rb")
        content = fileHandler.read()
        try:
            beans = json.loads(content)
            if beans is not None and len(beans) == streamAmount:
                playIndex = 0
                for bean in beans:
                    self.setPlayerRun(bean, playIndex)
                    playIndex += 1
        except Exception, e:
            self.logger.error("Can't load address data")
            self.logger.error(e)

    def getPlayerAddress(self, event):
        streamAmount = self.xAmount * self.yAmount
        s2 = 3
        s1 = streamAmount - s2
        params = {"machineNumber": self.machineNumber, "streamCount": s1, "ishd": 0}
        data = urllib.urlencode(params)
        params2 = {"machineNumber": self.machineNumber, "streamCount": s2, "ishd": 1}
        data2 = urllib.urlencode(params2)
        self.logger.info("System is looping every %d seconds" % self.periodTime)
        try:
            response = urllib2.urlopen(self.playAddress, data, 30)
            response2 = urllib2.urlopen(self.playAddress, data2, 30)
            if response.code == 200 and response2.code == 200:
                content = response.read()
                content2 = response2.read()
                if content is not None and content2 is not None:
                    try:
                        b1 = json.loads(content)
                        b2 = json.loads(content2)
                        if b1 and b2:
                            beans = []
                            for i in b1:
                                beans.append(i)
                            for j in b2:
                                beans.append(j)
                            if beans is not None and len(beans) == streamAmount:
                                playIndex = 0
                                for bean in beans:
                                    self.setPlayerRun(bean, playIndex)
                                    playIndex += 1
                    except Exception, e:
                        self.logger.error("Can't load address data")
                        self.logger.error(e)
                else:
                    self.logger.error("Get Request is empty")
            else:
                self.logger.error("Get Http server is not 200 status")
        except Exception, e:
            self.logger.error("Can't get rtp play address")
            self.logger.error(e)

    def setPlayerRun(self, bean, playIndex):
        """

        :param bean: one channel information
        :param playIndex: which player
        """
        try:
            streamUrl = bean['STREAM_URL']
            streamName = bean['STREAM_NAME']
            streamPlatform = bean['STREAM_PLATFORM']
            alarmSummary = bean['ALARM_SUM']
            player = self.players[playIndex]
            panel = self.panels[playIndex]
            if player is not None and panel is not None:
                player.stop()
                media = self.vlc.media_new(streamUrl, 'sub-filter=marq')

                player.set_media(media)
                player.set_xwindow(panel.GetHandle())
                player.audio_set_mute(True)
                player.play()
                try:
                    make = MakeMarquee(self.logger, player, streamName, streamPlatform, alarmSummary)
                    make.start()
                    time.sleep(1)
                except Exception, e:
                    self.logger.error("Make Marquee thread failed")
                    self.logger.error(e)

        except Exception, e:
            self.logger.error("Can't set player and url")
            self.logger.error(e)


def main():
    logFileName = os.path.join(os.getcwd(), 'player.log')
    logging.basicConfig(filename=logFileName, level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s')
    logger = logging.getLogger('player')
    logger.setLevel(logging.INFO)
    app = wx.App()
    myPlayer = Player(None, 'Sanss IPTV Player', logger)
    app.MainLoop()


if __name__ == '__main__':
    main()













